package net.lab1024.sa.gateway.processor;

import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.gateway.dto.ApiProcessDTO;
import net.lab1024.sa.gateway.dto.HttpRequestDTO;
import org.springframework.http.HttpMethod;
import org.springframework.http.codec.multipart.Part;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

@Slf4j
@Component
public class HttpProcessor implements IProcessor {

    // 注入 Spring WebFlux 提供的 WebClient（需提前配置）
    @Resource
    private WebClient webClient;

    // HttpProcessor.java (支持文件上传转发)
    @Override
    public Mono<Object> process(ApiProcessDTO dto) {
        HttpRequestDTO httpRequest = dto.getHttpRequest();
        MultiValueMap<String, Part> multipartData = (MultiValueMap<String, Part>) dto.getData();

        // 判断是否为文件上传请求
        if (multipartData != null) {
            // 构建Multipart请求体
            BodyInserters.MultipartInserter bodyInserter = BodyInserters.fromMultipartData(multipartData);
            return webClient.method(HttpMethod.valueOf(httpRequest.getMethod()))
                    .uri(httpRequest.getUri())
                    .headers(headers -> headers.addAll(httpRequest.getHeaders()))
                    .body(bodyInserter) // 转发文件流
                    .exchangeToMono(response -> response.bodyToMono(Object.class));
        } else {
            // 普通表单请求处理（原逻辑不变）
            return webClient.method(HttpMethod.valueOf(httpRequest.getMethod()))
                    .uri(httpRequest.getUri())
                    .body(BodyInserters.fromValue(httpRequest.getBody()))
                    .exchangeToMono(response -> response.bodyToMono(Object.class));
        }
    }

    /**
     * 根据 HttpRequestDTO 构建 WebClient 请求
     */
    private WebClient.RequestHeadersSpec<?> buildWebClientRequest(HttpRequestDTO requestDTO) {
        // 1. 获取 HTTP 请求方法（GET/POST/PUT/DELETE 等）
        HttpMethod httpMethod = HttpMethod.valueOf(requestDTO.getMethod().toUpperCase());

        // 2. 构建基础请求（方法 + URI）
        WebClient.RequestBodySpec requestSpec = webClient.method(httpMethod)
                .uri(requestDTO.getUri()); // 目标服务 URI（如 http://order-service/api/create）

        // 3. 添加请求头（如 Content-Type、Authorization 等）
        if (requestDTO.getHeaders() != null) {
            requestDTO.getHeaders().forEach((key, values) -> {
                values.forEach(value -> requestSpec.header(key, value));
            });
        }

        // 4. 添加请求体（GET 请求无 body，POST/PUT 等有 body）
        if (requestDTO.getBody() != null && !httpMethod.equals(HttpMethod.GET)) {
            return requestSpec.body(BodyInserters.fromValue(requestDTO.getBody()));
        }

        return requestSpec;
    }

}